

/*
    KVO(Key-Value Observing)，俗称键值监听。
    它提供一种机制，当指定的对象的属性被修改后，则对象就会接受到通知。
    简单的说就是每次指定的被观察的对象的属性被修改后，KVO就会自动通知相应的观察者了。
 
    KVO是“观察者”设计模式的一种应用,利用它可以很容易实现视图组件和数据模型的分离，当数据模型的属性值改变之后作为监听器的视图组件就会被激发，激发时就会回调监听器自身。
    这种模式有利于两个类间的解耦合，尤其是对于业务逻辑与视图控制 这两个功能的解耦合。
 
 KVO常用的方法
 1>注册指定Key路径的监听器
 - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
 相关参数:
 observer:观察者,也就是KVO通知的订阅者。订阅着必须实现
 observeValueForKeyPath:ofObject:change:context:方法
 keyPath：描述将要观察的属性，相对于被观察者。
 options：KVO的一些属性配置；有四个选项。
 options所包括的内容:
 NSKeyValueObservingOptionNew：change字典包括改变后的值
 NSKeyValueObservingOptionOld:   change字典包括改变前的值
 NSKeyValueObservingOptionInitial:注册后立刻触发KVO通知
 NSKeyValueObservingOptionPrior:值改变前是否也要通知（这个key决定了是否在改变前改变后通知两次）
 context: 上下文，这个会传递到订阅着的函数中，用来区分消息，所以应当是不同的。
 注意:不要忘记解除注册，否则会导致资源泄露
 
 2>删除指定Key路径的监听器：
 - (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath
 - (void)removeObserver:(NSObject *)observer     forKeyPath:(NSString *)keyPath  context:(void *)context
 
 3>回调监听
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
 keyPath：被监听的keyPath , 用来区分不同的KVO监听。
 object： 被观察修改后的对象（可以通过object获得修改后的值）
 change：保存信息改变的字典（可能有旧的值，新的值等）
 context：上下文，用来区分不同的KVO监听
 
 
 
 KVO的典型使用场景(model 与 view的同步)
 
 KVO和Context
 由于Context通常用来区分不同的KVO，所以context的唯一性很重要。通常，我的使用方式是通过在当前.m文件里用静态变量定义。
 static void * privateContext = 0;
 KVO与线程
 KVO的响应和KVO观察的值变化是在一个线程上的，所以，大多数时候，不要把KVO与多线程混合起来。除非能够保证所有的观察者都能线程安全的处理KVO
 KVO监听变化的值
 
 改变前和改变后分别为
 id oldValue = change[NSKeyValueChangeOldKey];
 id newValue = change[NSKeyValueChangeNewKey];
 
 
 */
